<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box1{width: 100px;height: 100px;background-color: red;position: absolute;left: 0;top:0;}
    .box2{width: 100px;height: 100px;background-color: green;position: absolute;left: 0;top:110px;}
    .line{width: 1px;height: 500px;background: black;position: absolute;left: 500px;top:0;}
  </style>
</head>
<body>
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="line"></div>
</body>
<script>

  const box1 = document.querySelector(".box1")
  const box2 = document.querySelector(".box2")
  
  box1.onclick = function(){
    move(box1, {left:500, top:100})
  }

  function move(ele, data){
    // 1. 开启计时器
    if(ele.t) return;
    ele.t = setInterval(()=>{
      console.log(1)
      // 清除计时器解决方式2-1：先设定一个状态，用来记录是否有属性没到目标
      let flag = true;
      // 2. 遍历对象解析要操作的属性和对应的目标
      for(let attr in data){
        // 3. 根据传入的元素和属性，获取当前属性值
        const now = parseInt(getStyle(ele, attr));
        // 4. 计算步长
        let speed = (data[attr] - now)/8;
        speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
        // 5. 根据当前值和步长值，计算元素应该移动到的位置
        ele.style[attr] = now + speed + "px";
        // 清除计时器解决方式2-2：如果有属性没到目标，改变初始状态值
        if(now !== data[attr]){
          flag = false;
        }
      }
      // 清除计时器解决方式2-3：状态值是否发生改变，如果没有改变，说明没有属性没到目标，可以清除计时器了
      if(flag){
        clearInterval(ele.t);
        ele.t = undefined;
      }

    }, 30)
  }
  
  // 停止计时器：
    // 问题：只要有一个属性到目标，就停止计时器，导致其他属性还没到目标
    // 解决：

    function getStyle(ele, attr){
      return ele.currentStyle ? ele.currentStyle[attr] : getComputedStyle(ele)[attr];
    }
    
    // function move(ele, data){
    //   // 1. 开启计时器
    //   if(ele.t) return;
    //   ele.t = setInterval(()=>{
  
    //     // 清除计时器解决方式1-1：获取最大的目标值
    //     const max = Math.max(...Object.values(data));
  
    //     // 2. 遍历对象解析要操作的属性和对应的目标
    //     for(let attr in data){
    //       // 3. 根据传入的元素和属性，获取当前属性值
    //       const now = parseInt(getStyle(ele, attr));
    //       // 4. 计算步长
    //       let speed = (data[attr] - now)/8;
    //       speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
    //       // 5. 根据当前值和步长值，计算元素应该移动到的位置
    //       ele.style[attr] = now + speed + "px";
    //       // 清除计时器解决方式1-2：判断任一属性如果到达最大目标值，即可清除
    //       if(now === max){
    //         clearInterval(ele.t)
    //         ele.t = undefined;
    //       }
  
    //     }
    //   }, 30)
    // }
  </script>
</html>